﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#include "CLKernel.h"

namespace UX_STL
{
namespace CLShell
{
	
/*
=================================================
	конструктор
=================================================
*/
	CLKernel::CLKernel():
		_pProgram(null), _pID(null)
	{
	}
		
/*
=================================================
	деструктор
=================================================
*/
	CLKernel::~CLKernel()
	{
	}
	
/*
=================================================
	создать ядро
=================================================
*/
	bool CLKernel::Create(CLProgram *pProg, uni_c_string pName)
	{
		CHECK_ERR( pProg != null and pName != null );

		Destroy();

		cl_int	i_cl_err = 0;
		CL_CALL_R( _pID = clCreateKernel( pProg->Id(), pName.cstr(), &i_cl_err ) );
		
		_pProgram = pProg;
		return true;
	}
	
/*
=================================================
	создать ядро
=================================================
*/
	bool CLKernel::Create(CLProgram *pProg, cl_kernel pKernel)
	{
		CHECK_ERR( pProg != null and pKernel != null );

		Destroy();

		_pProgram	= pProg;
		_pID		= pKernel;
		return true;
	}
	
/*
=================================================
	удалить ядро
=================================================
*/
	void CLKernel::Destroy()
	{
		_ReleaseRef();
		_pProgram	= null;
		_pID		= null;
	}

/*
=================================================
	возвращает имя функции ядра
=================================================
*/
	bool CLKernel::GetFuncName(string &sName) const
	{
		CHECK_ERR( _pID != null );

		cl_int	i_cl_err = 0;
		size_t	u_size	 = 0;

		CL_CALL_R( i_cl_err = clGetKernelInfo( _pID, CL_KERNEL_FUNCTION_NAME, 0, null, &u_size ) );
		
		sName.Reserve( u_size + 2 );

		CL_CALL_R( i_cl_err = clGetKernelInfo( _pID, CL_KERNEL_FUNCTION_NAME, (size_t)sName.Size(), (void *)sName.cstr(), null ) );
		return true;
	}
	
/*
=================================================
	возвращает количество аргументов
=================================================
*/
	uint CLKernel::GetNumArgs() const
	{
		CHECK_ERR( _pID != null );
		
		cl_int	i_cl_err	= 0;
		cl_uint	u_num_args	= 0;

		CL_CALL_RV( i_cl_err = clGetKernelInfo( _pID, CL_KERNEL_NUM_ARGS, sizeof(u_num_args), &u_num_args, null ), 0 );
		return u_num_args;
	}

	__UX_CL_RC_IMPL( CLKernel, _pID, Kernel, KERNEL )

//-------------------------------------------------------------------

}	// CLShell
}	// UX_STL